﻿using System.IO;
using System.Net;
using Google.Protobuf;

namespace ZFramework.Runtime
{
    //解析网络消息管理器：解析proto消息，封装proto消息
    public sealed class NetMessageMgr : FrameworkManagerBase
    {
        private string _networkChannelName = "Default";
        private int _reqId;
        private IEventManager _eventMgr;
        private INetworkChannel _gameNetworkChannel;
        private INetworkManager _networkManager;
        private ProtoPacketHandler _packetHandler;

        protected override void Awake()
        {
            base.Awake();
            _reqId = 0;
        }

        void Start()
        {
            _eventMgr = FrameworkManagerManager.GetManager<EventManager>();
            if (_eventMgr == null)
            {
                Log.Error("EventMgr is invalid.");
                return;
            }
            _networkManager = FrameworkManagerManager.GetManager<NetworkManager>();
            if (_networkManager == null)
            {
                Log.Error("NetworkManager is invalid.");
                return;
            }
            _gameNetworkChannel = _networkManager.CreateNetworkChannel(_networkChannelName, ServiceType.Tcp, new NetworkChannelHelper());
            _packetHandler = new ProtoPacketHandler();
            _gameNetworkChannel.RegisterHandler(_packetHandler);
            _eventMgr.Subscribe(NetworkConnectedEventArgs.EventId, OnNetworkConnected);
            _eventMgr.Subscribe(NetworkClosedEventArgs.EventId, OnNetworkClosed);
            _eventMgr.Subscribe(NetworkMissHeartBeatEventArgs.EventId, OnNetworkMissHeart);
            _eventMgr.Subscribe(NetworkErrorEventArgs.EventId, OnNetworkError);
            _eventMgr.Subscribe(NetworkCustomErrorEventArgs.EventId, OnNetworkCustomError);
        }

        public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
        {
        }

        public override void Shutdown()
        {
            _eventMgr.Unsubscribe(NetworkConnectedEventArgs.EventId, OnNetworkConnected);
            _eventMgr.Unsubscribe(NetworkClosedEventArgs.EventId, OnNetworkClosed);
            _eventMgr.Unsubscribe(NetworkMissHeartBeatEventArgs.EventId, OnNetworkMissHeart);
            _eventMgr.Unsubscribe(NetworkErrorEventArgs.EventId, OnNetworkError);
            _eventMgr.Unsubscribe(NetworkCustomErrorEventArgs.EventId, OnNetworkCustomError);
        }

        public void Connect(IPAddress ipAddress, int port)
        {
            if (_gameNetworkChannel.Connected)
            {
                Log.Error("socket已经连接成功");
                return;
            }

            _gameNetworkChannel.Connect(ipAddress, port);
        }

        public void Send(IMessage message)
        {
            var packet = CreatePacket(message);
            _gameNetworkChannel.Send(packet);
            Log.Error($"发送消息  arg=={packet.MsgName}");
        }

        public string GetMsgName(IMessage msg, bool bFullName)
        {
            var msgType = msg.GetType();
            var msgName = bFullName ? msgType.FullName : msgType.Name;
            return msgName;
        }

        public PacketC2S CreatePacket(IMessage message)
        {
            var msgName = GetMsgName(message, false);
            using (var ms = new MemoryStream())
            {
                message.WriteTo(ms);
                ms.Flush();
                var reqId = _reqId++;
                PacketC2S packet = PacketC2S.Create(reqId, msgName, ms.ToArray());
                return packet;
            }
        }

        //游戏服连接成功
        private void OnNetworkConnected(object sender, GameEventArgs e)
        {
            NetworkConnectedEventArgs args = e as NetworkConnectedEventArgs;
            if (args == null)
                return;
            if (args.NetworkChannel != _gameNetworkChannel)
                return;
            Log.Error("连接socket成功");
        }
        
        //游戏服连接断开
        private void OnNetworkClosed(object sender, GameEventArgs e)
        {
            NetworkClosedEventArgs args = e as NetworkClosedEventArgs;
            if (args == null)
                return;
            if (args.NetworkChannel != _gameNetworkChannel)
                return;
            Log.Error("游戏服连接断开");
        }
        
        //
        private void OnNetworkMissHeart(object sender, GameEventArgs e)
        {
            NetworkMissHeartBeatEventArgs args = e as NetworkMissHeartBeatEventArgs;
            if (args == null)
                return;
            if (args.NetworkChannel != _gameNetworkChannel)
                return;
        }
        
        private void OnNetworkError(object sender, GameEventArgs e)
        {
            NetworkErrorEventArgs args = e as NetworkErrorEventArgs;
            if (args == null)
                return;
            if (args.NetworkChannel != _gameNetworkChannel)
                return;
            Log.Error(Utility.Text.Format("OnNetworkError  error=={0}", args.ErrorMessage));
        }
        
        private void OnNetworkCustomError(object sender, GameEventArgs e)
        {
            NetworkCustomErrorEventArgs args = e as NetworkCustomErrorEventArgs;
            if (args == null)
                return;
            if (args.NetworkChannel != _gameNetworkChannel)
                return;
        }

    }
}